
import * as Cesium from 'cesium/Cesium'
import CesiumNavigation from "cesium-navigation-es6"
// import {Viewer} from "cesium/Cesium";
// import * as Cesium from "cesium/Source/Cesium"
//指北针插件
// import CesiumNavigation from "cesium-navigation-es6/CesiumNavigation";
// import * as Cesium from "cesium/Source/Cesium.js"
// import {Viewer} from "cesium/Source/Cesium.js"
// import * as Cesium from 'cesium/Cesium'

// import * as widget from "cesium/Widgets/widgets.css";
/**
 * 自定义三维相关的内容
 */
export default class ZMap3D {
    /**
     * 构造函数，参数opiton是一个对象
     * @param {*} opiton  对象，含有两个属性
     * opiton = {
     *  target:"map", //三维容器的id
     *  zoomTool:true //显示导航条
     * }
     */
    constructor(opiton = {}) {
        if (!opiton.target)
            opiton.target = 'map'
        // 创建三维对象
        this.viewer = this._initViewer(opiton.target)
        // 显示缩放工具条
        if (opiton.zoomTool)
            this._initNavigation()
    }
    /**
     * 初始化三维地球,该方法是私有函数，只能在该函数内部调用，不能通过对象调用
     * @param {*} dom 
     */
    _initViewer(dom) {
        let viewer = new Cesium.Viewer(dom, {
            animation: false, //是否显示动画控件
            baseLayerPicker: false, //是否显示图层选择控件
            geocoder: true, //是否显示地名查找控件
            timeline: false, //是否显示时间线控件
            sceneModePicker: true, //是否显示投影方式控件
            navigationHelpButton: false, //是否显示帮助信息控件
            infoBox: false, //是否显示点击要素之后显示的信息
            fullscreenButton: false, //全屏按钮
            geocoder: false, //右上角查询搜索
            homeButton: false, //home按钮
            sceneModePicker: false, //3d 2d选择器
            //加载在线谷歌地图
            imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
                url: "http://{s}.tianditu.gov.cn/img_c/wmts?service=wmts&request=GetTile&version=1.0.0" +
                    "&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}" +
                    "&style=default&format=tiles&tk=5d27dc75ca0c3bdf34f657ffe1e9881d",
                layer: "tdtCva",
                style: "default",
                format: "tiles",
                tileMatrixSetID: "c",
                subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
                tilingScheme: new Cesium.GeographicTilingScheme(),
                tileMatrixLabels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"],
                maximumLevel: 18,
                show: false
            })
        });
        //---------------------- 抗锯齿效果 -----------------------------------
        if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {//判断是否支持图像渲染像素化处理
            viewer.resolutionScale = window.devicePixelRatio;
        }
        viewer.scene.fxaa = true;
        viewer.scene.postProcessStages.fxaa.enabled = true;
        //---------------------- 抗锯齿效果 -----------------------------------
        return viewer
    }
    /**
     * 初始化罗盘
     */
    _initNavigation() {
        var options = {};
        // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
        options.defaultResetView = Cesium.Rectangle.fromDegrees(80, 22, 130, 50);
        // 用于启用或禁用罗盘。true是启用罗盘，false是禁用罗盘。默认值为true。如果将选项设置为false，则罗盘将不会添加到地图中。
        options.enableCompass = true;
        // 用于启用或禁用缩放控件。true是启用，false是禁用。默认值为true。如果将选项设置为false，则缩放控件将不会添加到地图中。
        options.enableZoomControls = true;
        // 用于启用或禁用距离图例。true是启用，false是禁用。默认值为true。如果将选项设置为false，距离图例将不会添加到地图中。
        options.enableDistanceLegend = true;
        // 用于启用或禁用指南针外环。true是启用，false是禁用。默认值为true。如果将选项设置为false，则该环将可见但无效。
        options.enableCompassOuterRing = true;
        CesiumNavigation(this.viewer, options);
    }
    /**
     * 显示3d坐标信息栏
     */
    show3DCoordinates() {
        let viewer = this.viewer
        //地图底部工具栏显示地图坐标信息
        var elementbottom = document.createElement("div");
        document.getElementsByClassName("cesium-viewer")[0].appendChild(elementbottom);
        elementbottom.className = "mapfootBottom";
        elementbottom.style.cssText += "position: fixed;right: 10px; bottom: 20px;background: black;color: white;padding:3px 5px";
        var coordinatesDiv = document.getElementById("_coordinates");
        if (coordinatesDiv) {
            coordinatesDiv.style.display = "block";
        } else {
            var _divID_coordinates = "_coordinates";
            coordinatesDiv = document.createElement("div");
            coordinatesDiv.id = _divID_coordinates;
            coordinatesDiv.className = "map3D-coordinates";
            coordinatesDiv.innerHTML = "<span id='cd_label' style='font-size:13px;text-align:center;font-family:微软雅黑;color:#edffff;'>暂无坐标信息</span>";
            //document.getElementById(this.mapDivId).appendChild(coordinatesDiv);
            document.getElementsByClassName("mapfootBottom")[0].appendChild(coordinatesDiv);
            var handler3D = new Cesium.ScreenSpaceEventHandler(
                viewer.scene.canvas);
            // 鼠标的移动事件
            handler3D.setInputAction(function (movement) {
                var pick = new Cesium.Cartesian2(movement.endPosition.x, movement.endPosition.y);
                if (pick) {
                    var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(pick), viewer.scene);
                    if (cartesian) {
                        //世界坐标转地理坐标（弧度）
                        var cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
                        if (cartographic) {
                            //海拔
                            var height = viewer.scene.globe.getHeight(cartographic);
                            //视角海拔高度
                            var he = Math.sqrt(viewer.scene.camera.positionWC.x * viewer.scene.camera.positionWC.x + viewer.scene.camera.positionWC.y * viewer.scene.camera.positionWC.y + viewer.scene.camera.positionWC.z * viewer.scene.camera.positionWC.z);
                            var he2 = Math.sqrt(cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z);
                            //地理坐标（弧度）转经纬度坐标
                            var point = [cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180];
                            if (!height) {
                                height = 0;
                            }
                            if (!he) {
                                he = 0;
                            }
                            if (!he2) {
                                he2 = 0;
                            }
                            if (!point) {
                                point = [0, 0];
                            }
                            coordinatesDiv.innerHTML = "<span id='cd_label' style='font-size:13px;text-align:center;font-family:微软雅黑;color:#edffff;'>" + "视角海拔高度:" + (he - he2).toFixed(2) + "米" + "&nbsp;&nbsp;&nbsp;&nbsp;海拔:" + height.toFixed(2) + "米" + "&nbsp;&nbsp;&nbsp;&nbsp;经度：" + point[0].toFixed(6) + "&nbsp;&nbsp;纬度：" + point[1].toFixed(6) + "</span>";
                        }
                    }
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        }
    }
    /**
     * 说明：加载3dtiles文件
     * @param {*} opiton  对象
     * {
     *  url：""" //3dtiles的地址，
     *  success： 加载成功的回调函数
     *  error：   加载失败的回调函数
     * }
     */
    showCesium3DTileset(opiton) {
        if (!opiton)
            return false
        if (!opiton.url) {
            if (opiton.error) {
                opiton.error("无3dtiles文件的url")
            } else {
                throw new Error("无3dtiles文件的url");
            }
            return false
        }
        // 根据url加载3dtiles文件   
        const tileset = new Cesium.Cesium3DTileset({ url: opiton.url });
        tileset.readyPromise
            .then((tileset) => {
                //  将3dtiles加载到地球上
                this.viewer.scene.primitives.add(tileset);
                // 3dtiles 加载成功过
                if (opiton.success) opiton.success(tileset)
                // 自动将场景移动到3dtiles
                this.viewer.flyTo(tileset);
            })
            .otherwise(function (error) {
                if (opiton.error) opiton.error(error)
            });
        return tileset
    }
    /**
     * 说明：移除Primitives对象
     * @param {*} data data参数可以是对象也可以是一个Primitives对象
     * 如：一次移除多个Primitives对象 ，采用 data=[Primitives1,Primitives2,Primitives3]
     *     一次移除一个Primitives对象 ，采用data=Primitives1
     */
    removePrimitives(data) {
        // 判断要移除的数据是否是数组
        if (Array.isArray(data)) {
            // 通过遍历逐个移除对象
            data.map((item, index) => {
                this.viewer.scene.primitives.remove(item)
            })
        } else {
            // 移除单个对象，直接进行移除
            this.viewer.scene.primitives.remove(data)
        }
    }
    /**
     * 说明：根据url加载geojson数据
     * @param {*} opiton 对象，
     * opiton= {
     *  url:"", geojson的地址
     *  base:false 是否显示原始的数据
     *  style: {   设置geojsonde加载数据样式
    *       stroke: new Cesium.Color.fromCssColorString("#5D92FD"),
            fill: Cesium.Color.RED,
            strokeWidth: 3,
     *  }
     *  success：函数 数据加载成功后的的回调函数
     * }
     */
    showGeoJson(opiton = {}) {
        if (!opiton)
            return false
        if (!opiton.url)
            throw new Error("无3dtiles文件的url");

        let _opiton = {
            base: true,
            style: {
                stroke: new Cesium.Color.fromCssColorString("#5D92FD"),
                fill: Cesium.Color.RED,
                strokeWidth: 3,
            }
        }
        // 将默认数据和传入数据进行解构组合
        opiton = { ..._opiton, ...opiton }
        var promise = Cesium.GeoJsonDataSource.load(opiton.url, opiton.style);
        promise.then((dataSource) => {
            if (opiton.success) opiton.success(dataSource)
            // 是否显示原始数据
            if (opiton.base)
                this.viewer.dataSources.add(dataSource);

            return dataSource
        })
    }
    /**
     * 移除geojson数据
     * @param {*} dataSource 
     */
    removeGeojson(dataSource) {
        if (dataSource)
            this.viewer.dataSources.remove(dataSource);
    }
    /**
     * 说明：添加点信息
     * @param {*} option 对象
     * option = {
     *     points:[{         //显示的标注点信息，该字段必须含有lon(经度),lat(纬度)，height(非必填，高程信息)
     *          lon:113.4,
     *          lat:34.6，
     *          height：0
     *     }]，
     *     style：function（e）{ //自定义的图标函数，必须有返回值
     *          return e
     *     }， 
     *     layerId："图层信息”   图层的名称，唯一值，必填
     * }
     * 
     */
    addPoints(option) {
        if (!option)
            return
        if (option.points) {
            let layer = []
            option.points.map((item, index) => {
                let enetity = {
                    name: '标点',
                    position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat, item.height ? item.height : 0),
                }
                if (typeof option.style === "function") {
                    let n_item = option.style(item)
                    enetity.billboard = {
                        image: n_item.icon ? n_item.icon : "",
                        width: 24,
                        height: 24,
                    }
                } else {
                    enetity.point = {
                        color: Cesium.Color.RED,    //点位颜色
                        pixelSize: 10                //像素点大小
                    }
                }
                if (option.layerId)
                    enetity.layerId = option.layerId
                enetity["data"] = item
                let enetity_ = this.viewer.entities.add(enetity)
                layer.push(enetity_)
            })
            return layer
        }
    }
    /**
     * 移除点信息
     * @param {*} layer 
     */
    removePointLayer(layer) {
        if (layer) {
            layer.map((item, index) => {
                this.viewer.entities.remove(item)
            })
        }
    }


}
